package xin.petstore.framework.web.sitemesh;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

class Xml {
    private final Element element;

    public Xml(Element element) {
        this.element = element;
    }

    public Xml() {
        this.element = null;
    }

    public Xml(String xml) {
        try {
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = builder.parse(new InputSource(new StringReader(xml)));
            this.element = document.getDocumentElement();
        } catch (ParserConfigurationException e) {
            throw new IllegalStateException(e);
        } catch (SAXException e) {
            throw new IllegalArgumentException("Could not parse XML:\n" + xml, e);
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public String attribute(String name) {
        return (this.element == null) || (!this.element.hasAttribute(name)) ? null : this.element.getAttribute(name);
    }

    public String attribute(String name, String defaultValue) {
        return valueIfNotNull(attribute(name), defaultValue);
    }

    public String text() {
        return this.element == null ? null : this.element.getTextContent();
    }

    public String text(String defaultValue) {
        return valueIfNotNull(text(), defaultValue);
    }

    public List<Xml> children(String tagName) {
        if (this.element == null) {
            return Collections.emptyList();
        }
        NodeList nodeList = this.element.getChildNodes();
        List result = new ArrayList(nodeList.getLength());
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if ((node instanceof Element)) {
                Element element = (Element) node;
                if (element.getTagName().equals(tagName)) {
                    result.add(new Xml((Element) node));
                }
            }
        }
        return result;
    }

    public Xml child(String tagName) {
        if (this.element == null) {
            return new Xml();
        }
        NodeList nodeList = this.element.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if ((node instanceof Element)) {
                Element element = (Element) node;
                if (element.getTagName().equals(tagName)) {
                    return new Xml((Element) node);
                }
            }
        }
        return new Xml();
    }

    public boolean exists() {
        return this.element != null;
    }

    private String valueIfNotNull(String value, String defaultValue) {
        return value == null ? defaultValue : value;
    }
}
